#include "stdafx.h"
#include "FrameManage.h"



void FrameResourceObj::UpdateLight()
{
	shared_ptr<LightManage> pvLight = LightManage::GetLightCurrent();
	m_cbCurrentlight = MallocBufffer(m_cbCurrentlight, pvLight->Count(), true);
	
	vector<string> vName = pvLight->GetKeys();
	for (int i=0; i<vName.size(); ++i)
	{
		const LightObj& light = pvLight->Get(vName[i]);
		m_cbCurrentlight->CopyData(i, light.GetLightData());
	}

}

void FrameResourceObj::UpdateCamera()
{
	vector<string> vStrCamera = CameraManage::GetInstance()->GetKeys();
	m_cbGlobalCamera = MallocBufffer(m_cbGlobalCamera, vStrCamera.size(), true);
	for (int i=0; i<vStrCamera.size(); ++i)
	{
		shared_ptr<CameraConstants> pCam = CameraManage::GetInstance()->Get(vStrCamera[i]);
		m_cbGlobalCamera->CopyData(i, *pCam);

	}


}

void FrameResourceObj::UpdateSkinData()
{
	m_cbCurSkin = nullptr;
}

void FrameResourceObj::UpdateObj(const vector<ScenRenderItem>& vRenderItem)
{
	m_cbCurObject = MallocBufffer(m_cbCurObject, vRenderItem.size(), true);
	for (int i=0; i<vRenderItem.size(); ++i)
	{
		ScenRenderItem item = vRenderItem[i];
		ObjectConstantsBuffer buffer;
		for (int i=0; i<min(sizeof(buffer.m_inxLight)/sizeof(buffer.m_inxLight[0]), item.m_vLightInx.size()); ++i)
		{
			buffer.m_inxLight[i] = item.m_vLightInx[i];
		}
		buffer.m_inxMaterial = MaterialManage::GetInstance()->GetKeyInx(item.m_pMaterialObj->GetName());
		buffer.m_matWorld = item.m_matWorld;
		m_cbCurObject->CopyData(i, buffer);
	}
	m_vRenderItem = vRenderItem;
}

void FrameResourceObj::UpdateMaterial()
{
	shared_ptr<MaterialManage>  pManage = MaterialManage::GetInstance();
	m_cbObjectMat = MallocBufffer(m_cbObjectMat, pManage->Count(), false);
	vector<string> strName = pManage->GetKeys();
	for (int i = 0; i < strName.size(); ++i)
	{
		shared_ptr<MaterialObj> pMat = pManage->Get(strName[i]);
		m_cbObjectMat->CopyData(i, pMat->GetData());
	}
}

void FrameResourceObj::UpdateTex()
{
	TextureObjManage::GetInstance()->UpdateAllRes();
	m_vStrTexName = TextureObjManage::GetInstance()->GetTexNames();
}

void FrameResourceObj::BindObjResource(int inxObjConstBuffer, int inxObjSkin)
{

	auto objectCB = m_cbCurObject->Resource();
	UINT objCBByteSize = d3dUtil::CalcConstantBufferByteSize(sizeof(ObjectConstantsBuffer));
	UINT skinnedCBByteSize = d3dUtil::CalcConstantBufferByteSize(sizeof(SkinnedConstantsBuffer));
	D3D12_GPU_VIRTUAL_ADDRESS objCBAddress = objectCB->GetGPUVirtualAddress() + inxObjConstBuffer*objCBByteSize;
	m_pCommandList->SetGraphicsRootConstantBufferView(TYPE_OBJ_BUFFER, objCBAddress);
	if (inxObjSkin >=0)
	{
		auto skinnedCB = m_cbCurSkin->Resource();
		D3D12_GPU_VIRTUAL_ADDRESS skinnedCBAddress = skinnedCB->GetGPUVirtualAddress() + inxObjSkin;
		m_pCommandList->SetGraphicsRootConstantBufferView(TYPE_OBJ_SKIN_ANIMATION_BUFFER, skinnedCBAddress);
	}
	else
	{
		m_pCommandList->SetGraphicsRootConstantBufferView(TYPE_OBJ_SKIN_ANIMATION_BUFFER, 0);
	}
}

void FrameResourceObj::BindResource()
{
	BindMaterial();
	BindTex();
	BindLight();
	BindCamera();

	ID3D12DescriptorHeap* descriptorHeaps[] = { TextureObjManage::GetInstance()->GetTexDescriptorHeap().Get() };
	m_pCommandList->SetDescriptorHeaps(_countof(descriptorHeaps), descriptorHeaps);

//	UpdateRes(TYPE_TEXTURE_2D, m_cbCurrentlight->Resource());
	D3D12_GPU_DESCRIPTOR_HANDLE handleSky = TextureObjManage::GetInstance()->GetSkyGpuStart();
	m_pCommandList->SetGraphicsRootDescriptorTable((int)FrameResourceObj::TYPE_TEXTURE_CUBE, handleSky);

	D3D12_GPU_DESCRIPTOR_HANDLE handle = TextureObjManage::GetInstance()->GetTexDescriptorHeap()->GetGPUDescriptorHandleForHeapStart();
	m_pCommandList->SetGraphicsRootDescriptorTable((int)FrameResourceObj::TYPE_TEXTURE_2D, handle);
	//BindSkinData();
	//BindObj();
}

void FrameResourceObj::BindTex()
{
	
}

void FrameResourceObj::BindLight()
{
	UpdateRes(TYPE_LIGHT_DATA, m_cbCurrentlight->Resource());

}
void FrameResourceObj::BindCamera()
{
	UpdateRes(TYPE_GLOBAL_DATA, m_cbGlobalCamera->Resource());
}
void FrameResourceObj::BindSkinData()
{

}
void FrameResourceObj::BindMaterial()
{
	UpdateRes(TYPE_MATERIAL_DATA, m_cbObjectMat->Resource());
}
